package artibella.ui.scrolls
{
	import artibella.IDisposable;
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	
	import caurina.transitions.Tweener;
	
	/**
	 * ...
	 * @author pbordachar
	 */
	
	public class ScrollBar extends Sprite implements IDisposable
	{
		private var _up:Sprite;
		private var _down:Sprite;
		private var _timer:Timer;
		private var _frequence:int;
		private var _frequInit:int = 500;
		
		private var _bar:Sprite;
		private var _scroller:AdaptableScroller;
		private var _adaptable:Boolean;
		
		private var _box:ScrollBox;
		private var _smooth:Boolean;
		
		private var _stage:Stage;
		
		public function ScrollBar( box:ScrollBox, smoothed:Boolean = false ) 
		{
			_box = box;
			_smooth = smoothed;
			
			_box.setScrollingTool( this );
		}
		
		// - - -
		
		public function setUpBtn( c:Sprite ):void
		{
			_up = c;
			addChild( _up );
		}
		
		public function setDownBtn( c:Sprite ):void
		{
			_down = c;
			addChild( _down );
		}
		
		public function setBar( c:Sprite ):void
		{
			_bar = c;
			addChildAt( _bar, 0 );
		}
		
		public function setScroller( c:AdaptableScroller, adaptable:Boolean = false ):void
		{
			_adaptable = adaptable;
			
			_scroller = c;
			_scroller.y = 0;
			addChild( _scroller );
			
			if ( _adaptable ) {
				var hauteurScroll:Number = _bar.height / _box.ratio;
				_scroller.setHeight( hauteurScroll );
			}
		}
		
		// - - -
		
		public function updatedContent( r:Number ):void 
		{
			if ( r <= 1 ) {
				_activated( false );
			} else {
				
				_activated( true );
				_scroller.y = 0;
					
				if (_adaptable ) {
					var hauteurScroll:Number = _bar.height / _box.ratio;
					_scroller.setHeight( hauteurScroll );
				}
			}
		}
		
		protected function _activated( b:Boolean ):void
		{
			visible = b;
			
			if( b ) {
				
				if ( _up != null ) {
					_up.buttonMode = true;
					_up.addEventListener( MouseEvent.MOUSE_DOWN, _upOnHandler );
					_up.addEventListener( MouseEvent.MOUSE_UP, _upOutHandler );
					_up.addEventListener( MouseEvent.ROLL_OUT, _upOutHandler );
				}
				
				if ( _down != null ) {
					_down.buttonMode = true;
					_down.addEventListener( MouseEvent.MOUSE_DOWN, _downOnHandler );
					_down.addEventListener( MouseEvent.MOUSE_UP, _downOutHandler );
					_down.addEventListener( MouseEvent.ROLL_OUT, _downOutHandler );
				}
				
				if ( _bar != null ) {
					_bar.buttonMode = false;
					_bar.addEventListener( MouseEvent.CLICK, _barHandler );
				}
				
				if ( _scroller != null ) {
					_scroller.buttonMode = true;
					_scroller.addEventListener( MouseEvent.MOUSE_DOWN, _dragHandler );
				}

			} else {
				
				if ( _up != null ) {
					_up.buttonMode = false;
					_up.removeEventListener( MouseEvent.MOUSE_DOWN, _upOnHandler );
					_up.removeEventListener( MouseEvent.MOUSE_UP, _upOutHandler );
					_up.removeEventListener( MouseEvent.ROLL_OUT, _upOutHandler );
				}
				
				if ( _down != null ) {
					_down.buttonMode = false;
					_down.removeEventListener( MouseEvent.MOUSE_DOWN, _downOnHandler );
					_down.removeEventListener( MouseEvent.MOUSE_UP, _downOutHandler );
					_down.removeEventListener( MouseEvent.ROLL_OUT, _downOutHandler );
				}
				
				if ( _bar != null ) {
					_bar.buttonMode = false;
					_bar.removeEventListener( MouseEvent.CLICK, _barHandler );
				}
				
				if ( _scroller != null ) {
					_scroller.buttonMode = false;
					_scroller.removeEventListener( MouseEvent.MOUSE_DOWN, _dragHandler );
				}
			}
		}
		
		// - - -
		
		private function _dragHandler( e:MouseEvent ):void
		{
			_scroller.removeEventListener( MouseEvent.MOUSE_DOWN, _dragHandler );
			
			var hauteur:Number = _bar.height - _scroller.getHeight();
			var rect:Rectangle = new Rectangle( _scroller.x, 0, 0, hauteur );
			_scroller.startDrag( false, rect );
			
			_stage = stage;
			
			_stage.addEventListener( MouseEvent.MOUSE_UP, _dropHandler );
			addEventListener( Event.ENTER_FRAME, _enterFrameHandler );
			
		}
		
		private function _dropHandler( e:MouseEvent ):void
		{
			_stage.removeEventListener( MouseEvent.MOUSE_UP, _dropHandler );
			removeEventListener( Event.ENTER_FRAME, _enterFrameHandler );
			
			_scroller.stopDrag();
			
			_scroller.addEventListener( MouseEvent.MOUSE_DOWN, _dragHandler );
			
		}
		
		private function _enterFrameHandler( e:Event ):void
		{
			var hauteur:int = _bar.height - _scroller.getHeight();
			var percent:Number = _scroller.y / hauteur;
		
			_box.setRelativeLocation( percent, _smooth );
		}
		
		// - - -
		
		private function _upOnHandler( e:Event ):void
		{
			var posY:int = _box.getLocation();
			_box.setLocation( posY + 10 );
			
			if ( _timer == null ) {
				
				_frequence = _frequInit;
				_timer = new Timer( _getFrequency() )
				_timer.addEventListener( TimerEvent.TIMER, _upOnHandler );
				_timer.start();
				
			} else {
				
				_timer.delay = _getFrequency();
			}
		}
		
		private function _upOutHandler( e:MouseEvent ):void
		{
			if( _timer != null ){
				_timer.stop();
				_timer.removeEventListener( TimerEvent.TIMER, _upOnHandler );
				_timer = null;
			}
		}
		
		private function _downOnHandler( e:Event ):void
		{
			var posY:int = _box.getLocation();
			_box.setLocation( posY - 10 );
			
			if ( _timer == null ) {
				
				_frequence = _frequInit;
				_timer = new Timer( _getFrequency() )
				_timer.addEventListener( TimerEvent.TIMER, _downOnHandler );
				_timer.start();
				
			} else {
				
				_timer.delay = _getFrequency();
			}
		}
		
		private function _downOutHandler( e:MouseEvent ):void
		{
			if( _timer != null ){
				_timer.stop();
				_timer.removeEventListener( TimerEvent.TIMER, _downOnHandler );
				_timer = null;
			}
		}
		
		private function _getFrequency():int 
		{
			var freq:int = _frequence;
			
			if ( freq == _frequInit ) {
				_frequence = 30;
			} 
			
			return freq;
		}
		
		// - - -
		
		private function _barHandler( e:MouseEvent ):void
		{
			var percent:Number = mouseY / _bar.height;
			
			_box.setRelativeLocation( percent, _smooth );
			
			var hauteur:int = _bar.height - _scroller.getHeight();
			var posY:int = percent * hauteur;
			
			Tweener.addTween( _scroller, { y:posY, time:.5 } );
		}
		
		public function setScrollerLocation( percent:Number ):void
		{
			if ( _scroller ) {
				
				var hauteur:int = _bar.height - _scroller.getHeight();
				_scroller.y = percent * hauteur;
			}
		}
		
		// - - - IDisposable
		
		public function dispose():void
		{
			_activated( false );
			
			if( _stage ) _stage.removeEventListener( MouseEvent.MOUSE_UP, _dropHandler );
			removeEventListener( Event.ENTER_FRAME, _enterFrameHandler );
			
			_up = null;
			_down = null;
			_bar = null;
			_scroller = null;
			_box = null;
			_stage = null;
		}
	}
}